using System;
using System.Xml;
using System.Collections;
using System.Runtime.InteropServices;

namespace ScenarioFramework.Modules.PCM.DataModel.ConfigurationManager.Property
{
	//*********************************************************************
	//
	// XMLGroupProperties Class
	//
	// The XMLGroupProperties class represents a collection base of XMLGroupProperties
	// Its imports methods from WAPI.XmlObjectSet like get set and add
	//
	//*********************************************************************
	public class XMLPropertiesGroup : bOSdotNET.XML.Data.XMLObjectSet 
	{
		/** FIELDS **/
		public const string MAIN_NODE	= "GroupProperties";

		private const string GROUP_ATTRIBUTE = "Group";

		public string sGroup;

		/** CONSTRUCTORS **/

		/** CONSTRUCTOR Empty **/
		public XMLPropertiesGroup()
		{
			this.Init();
		}

		/** CONSTRUCTOR Width xml parsering**/
		public XMLPropertiesGroup(System.Xml.XmlNode node)
		{
			this.Parse(node);
		}

		/** PROPERTIES **/
		public string Group 
		{
			get { return sGroup; }
			set { sGroup = value; }
		}

		/** INSTANCE METHODS **/

		/** Parsering method for filling the Properties Empty **/
		override public void Init()
		{
			this.RemoveAll();

			sGroup= string.Empty;
		}

		/** Parsering method for filling the Properties **/
		override public void Parse(System.Xml.XmlNode node2Parse)
		{
			this.Init();

			System.Xml.XmlNode node;

			/** find the attributes situated on the root tag **/
			for ( int i=0; i<node2Parse.Attributes.Count;i++)
			{
				node = node2Parse.Attributes.Item(i);

				switch ( node2Parse.Attributes.Item(i).Name ) 
				{
					case XMLPropertiesGroup.GROUP_ATTRIBUTE:
						sGroup = node.InnerText;
						break;
				}
			}

			for ( int i=0; i<node2Parse.ChildNodes.Count;i++)
			{
				node = node2Parse.ChildNodes[i];

				switch ( node.Name) 
				{
					case XMLProperty.MAIN_NODE:
						this.Add ( new XMLProperty(node));
						break;
				}
			}
		}

		override public bOSdotNET.XML.XMLNode GetXMLNode()
		{
			bOSdotNET.XML.XMLNode xmlNode = new bOSdotNET.XML.XMLNode(XMLPropertiesGroup.MAIN_NODE);
			xmlNode.AddAttribute ( new bOSdotNET.XML.XMLAttribute ( XMLPropertiesGroup.GROUP_ATTRIBUTE , sGroup) );

			for ( int i=0; i<this.Count;i++)
			{
				xmlNode.AddNode ( this[i].GetXMLNode() );
			}

			return xmlNode;
		}

		/** Method witch return the XmlString width the properties filled **/
		public XMLProperty Get(string sName)
		{
			XMLProperty property;

			for ( int i=0; i<this.List.Count; i++)
			{
				property = (XMLProperty)this.List[i];
				if ( property.Name == sName )
				{
					return property;
				}
			}

			throw new Exception.PropertyNotFound(sName + " not found.");
		}

		

		/** Method for checking a property in collection **/
		public bool AlmostIn(XMLPropertiesGroup vValues)
		{
			XMLProperty leftProperty;
			XMLProperty rightProperty;

			for ( int i=0; i<this.List.Count; i++)
			{
				leftProperty = (XMLProperty)this.List[i];

				try
				{
					rightProperty = vValues.Get(leftProperty.Name);
				}
				catch ( Exception.PropertyNotFound)
				{
					return false;
				}
			}
			
			return true;
		}

		/** Method for checking a property in collection **/
		public bool AlmostInByName (string sName)
		{
			XMLProperty Property;

			for ( int i=0; i<this.List.Count; i++)
			{
				Property = (XMLProperty)this.List[i];

				if (Property.Name == sName)
				{
					return true;
				}
			}
			
			return false;
		}

		/** method to remove a property from collection by its name**/
		public bool RemoveByName(string sName)
		{
			XMLProperty Property;

			for ( int i=0; i<this.List.Count; i++)
			{
				Property = (XMLProperty)this.List[i];

				if (Property.Name == sName)
				{
					this.List.Remove(Property);
					return true;
				}
			}
			
			return false;
		}

		/** SORTING  FIELDS **/

		public enum SortFields 
		{
			Name,
			Type,
			Description
		}

		/** SORTING METHODS **/


		public void Sort(SortFields sortField, bool isAscending) 
		{
			switch (sortField) 
			{
				case SortFields.Name:
					InnerList.Sort(new NameComparer());
					break;
				case SortFields.Type:
					InnerList.Sort(new TypeComparer());
					break;
				case SortFields.Description:
					InnerList.Sort(new DescriptionComparer());
					break;
				
			}
			if (!isAscending) InnerList.Reverse();
		}


		private sealed class NameComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLProperty first = (XMLProperty) x;
				XMLProperty second = (XMLProperty) y;
				return first.Name.CompareTo(second.Name);
			}
		}

		private sealed class TypeComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLProperty first = (XMLProperty) x;
				XMLProperty second = (XMLProperty) y;
				return first.Type.CompareTo(second.Type);
			}
		}

		private sealed class DescriptionComparer : IComparer 
		{
			public int Compare(object x, object y) 
			{
				XMLProperty first = (XMLProperty) x;
				XMLProperty second = (XMLProperty) y;
				return first.Description.CompareTo(second.Description);
			}
		}

		
	}
}